package com.example.forum.controller;


import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.example.forum.MyQuery;
import com.example.forum.commons.authrization.TokenManager;
import com.example.forum.commons.tools.StringUtil;
import com.example.forum.commons.tools.Transfer.DataTransfer;
import com.example.forum.entity.TMenus;
import com.example.forum.entity.TPermissions;
import com.example.forum.service.ITMenusService;
import com.example.forum.service.ITPermissionsService;
import com.example.forum.vo.JsonResult;
import com.example.forum.vo.MenuModel;
import com.example.forum.vo.TreeMenuModel;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import net.logstash.logback.encoder.org.apache.commons.lang.ArrayUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import javax.validation.Valid;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 * 前端控制器
 * </p>
 *
 * @author why
 * @since 2019-10-30    11
 */

@RestController
@Api(tags = "菜单控制层")
@RequestMapping("/Menu")
public class TMenusController extends BaseController {

    private static final Logger LOGGER = LoggerFactory.getLogger(TMenusController.class);

    @Autowired
    private ITPermissionsService permissionsService;
    @Autowired
    DataTransfer dataTransfer;
    @Autowired
    private TokenManager tokenManager;
    @Autowired
    private ITMenusService menuService;

    @ApiOperation(value = "更新菜单")
    @RequestMapping(value = "/update", method = {RequestMethod.POST})
    public JsonResult update(
            @Valid @RequestBody @ApiParam(name = "角色对象", value = "传入json格式", required = true) MenuModel menumodel) {

        var menuDto = menuService.getById(menumodel.getId());
        if (menuDto == null) {
            return new JsonResult(HttpStatus.NOT_FOUND, "该菜单不存在", null);
        }

        menuDto.setName(menumodel.getName());
        menuDto.setPermissiontarget(menumodel.getPermissionTarget());
        menuDto.setUrl(menumodel.getUrl());
        menuDto.setIcon(menumodel.getIcon());
        menuDto.setOrderin(menumodel.getOrderIn());

        if (!StringUtil.isEmpty(menumodel.getPermissionTarget())) {
            var permissions = permissionsService.list(new QueryWrapper<TPermissions>().
                    eq("TargetName", menumodel.getPermissionTarget()));

            if (permissions == null || permissions.size() == 0) {

                TPermissions pdto = new TPermissions();
                pdto.setDisplayname(menumodel.getName());
                pdto.setTargetname(menumodel.getPermissionTarget());
                pdto.setDescription("菜单权限");
                pdto.setCreatoruserid(currentUserId());
                pdto.setPermissiontype(1);
                permissionsService.save(pdto);
            }
        }
        menuService.updateById(menuDto);
        return new JsonResult(HttpStatus.OK, "更新成功", null);
    }


    @ApiOperation(value = "添加菜单")
    @RequestMapping(value = "/create", method = {RequestMethod.POST})
    public JsonResult create(
            @Valid @RequestBody @ApiParam(name = "菜单对象", value = "传入json格式", required = true) MenuModel menumodel) {
        var menuDto = menuService.getOne(new QueryWrapper<TMenus>()
                .eq("name", menumodel.getName())
                .eq("isdeleted", 0));
        if (menuDto != null) {
            return new JsonResult(HttpStatus.BAD_REQUEST, "该菜单已存在", null);
        }
        TMenus menu = new TMenus();
        menu.setName(menumodel.getName());
        menu.setPermissiontarget(menumodel.getPermissionTarget());
        menu.setUrl(menumodel.getUrl());
        menu.setOrderin(0);
        menu.setIcon(menumodel.getIcon());
        if (menumodel.getOrderIn() != null)
            menu.setOrderin(menumodel.getOrderIn());
        if (menumodel.getParentId() != null)
            menu.setParentid(menumodel.getParentId());
        menuService.save(menu);
        return new JsonResult(HttpStatus.OK, "添加成功", null);
    }

    @ApiOperation(value = "获取菜单")
    @RequestMapping(value = "/getInfo", method = {RequestMethod.GET})
    public JsonResult getInfo(String menuId) {
        var menu = menuService.getById(menuId);
        return new JsonResult(HttpStatus.OK, "获取菜单 ", menu);
    }


    @ApiOperation(value = "根据名称获取菜单")
    @RequestMapping(value = "/getMenuByName", method = {RequestMethod.GET})
    public JsonResult getMenuByName(String name) {
        if (StringUtil.isEmpty(name)) {
            return new JsonResult(HttpStatus.BAD_REQUEST, "名称不能为空", null);
        }
        var menus = menuService.list(new QueryWrapper<TMenus>().like("name", name).eq("isdeleted",0));
        return new JsonResult(HttpStatus.OK, "成功 ", menus);
    }


    @ApiOperation(value = "添加菜单")
    @RequestMapping(value = "/InsertTree", method = {RequestMethod.POST})
    public JsonResult InsertTree(String pid, String name) {
        var menuDto = menuService.getOne(new QueryWrapper<TMenus>().eq("name", name).eq("parentId", pid));
        if (menuDto != null) {
            return new JsonResult(HttpStatus.BAD_REQUEST, "该菜单已存在", null);
        }
        TMenus menu = new TMenus();
        menu.setName(name);
        menu.setParentid(pid);
        menuService.save(menu);
        return new JsonResult(HttpStatus.OK, "添加成功", null);
    }

    @ApiOperation(value = "删除菜单")
    @RequestMapping(value = "/delete", method = {RequestMethod.POST})
    public JsonResult delete(String menuId) {
        var menuDto = menuService.getById(menuId);
        if (menuDto == null) {
            return new JsonResult(HttpStatus.NOT_FOUND, "该菜单不存在", null);
        }
        menuDto.setIsdeleted(true);
        menuDto.setDeleteruserid(currentUserId());
        menuService.updateById(menuDto);
        return new JsonResult(HttpStatus.OK, "删除成功", null);
    }

    /// <summary>
    /// 递归树结构
    /// </summary>
    /// <param name="TreeNodes"></param>
    /// <param name="treeModel"></param>
    private void CreateTreeMenuView(List<TreeMenuModel> TreeNodes, TreeMenuModel treeModel) {
        var childs = TreeNodes.stream()
                .filter(m -> m.getParentid() != null && treeModel.getId().equals(m.getParentid()))
                .collect(Collectors.toList());
        if (childs != null && childs.size() > 0) {
            List<TreeMenuModel> childrens = childs.stream().sorted(Comparator.comparing(TreeMenuModel::getOrderin))
                    .collect(Collectors.toList());

            treeModel.setMenuItems(new ArrayList<TreeMenuModel>());
            childrens.forEach(m -> {

                treeModel.MenuItems.add(m);
                CreateTreeMenuView(TreeNodes, m);
            });
        } else {

            treeModel.setMenuItems(new ArrayList<TreeMenuModel>());
        }

    }


    @ApiOperation(value = "获取所有菜单")
    @RequestMapping(value = "/getMenuAll", method = {RequestMethod.GET})
    public JsonResult getMenuAll() {
        LOGGER.info("获取菜单");
        var menus = menuService.list(new MyQuery<>()).stream().filter(m -> m.getIsdeleted().equals(false)).sorted(Comparator.comparing(TMenus::getOrderin))
                .collect(Collectors.toList());
        var Outmodels = new ArrayList<TreeMenuModel>();
        var OutmodelResults = new ArrayList<TreeMenuModel>();
        var basemenu = menus.stream().filter(m -> m.getParentid() == null).collect(Collectors.toList());
        menus.forEach(menu -> {
            var old = new TreeMenuModel();
            old = (TreeMenuModel) dataTransfer.getObjectFromObject(old, menu);
            Outmodels.add(old);
        });
        if (basemenu != null && basemenu.size() > 0) {
            basemenu.forEach(bm -> {
                var old = new TreeMenuModel();
                old = (TreeMenuModel) dataTransfer.getObjectFromObject(old, bm);
                CreateTreeMenuView(Outmodels, old);
                OutmodelResults.add(old);
            });
        }
        return new JsonResult(HttpStatus.OK, "成功 ", OutmodelResults);
    }


    @ApiOperation(value = "获取当前用户所有菜单")
    @RequestMapping(value = "/getCurrentMenuAll", method = {RequestMethod.GET})
    public JsonResult getCurrentMenuAll() {
        LOGGER.info("获取当前用户所有菜单");
        String[] permissions = currentUser().getPermissions().split(";");
        var menus = menuService.list().stream().filter(m -> m.getIsdeleted().equals(false)).sorted(Comparator.comparing(TMenus::getOrderin))
                .collect(Collectors.toList());
        List<TreeMenuModel> Outmodels = new ArrayList<TreeMenuModel>();
        var OutmodelResults = new ArrayList<TreeMenuModel>();
        var basemenu = menus.stream().filter(m -> m.getParentid() == null).collect(Collectors.toList());

        menus.forEach(menu -> {
            if (ArrayUtils.contains(permissions, menu.getPermissiontarget())) {
                var old = new TreeMenuModel();
                old = (TreeMenuModel) dataTransfer.getObjectFromObject(old, menu);
                Outmodels.add(old);
            }
        });
        if (basemenu != null && basemenu.size() > 0) {
            basemenu.forEach(bm -> {
                if (!ArrayUtils.contains(permissions, bm.getPermissiontarget())) {
                    return;
                }
                var old = new TreeMenuModel();
                old = (TreeMenuModel) dataTransfer.getObjectFromObject(old, bm);
                CreateTreeMenuView(Outmodels, old);
                OutmodelResults.add(old);
            });
        }
        return new JsonResult(HttpStatus.OK, "成功 ", OutmodelResults);
    }


    @ApiOperation(value = "分页查询")
    @RequestMapping(value = "/getList", method = {RequestMethod.GET})
    public JsonResult getList(String name, Integer pageIndex, Integer pageSize) {
        Page<TMenus> page = new Page(pageIndex, pageSize);
        var list = menuService.page(page, new QueryWrapper<TMenus>()
                .eq(StringUtil.isNotEmpty(name), "name", name)
                .eq("isdeleted", 0)
        );
        return new JsonResult(HttpStatus.OK, "成功 ", list);
    }
}

